﻿using System.Transactions;
using AutoMapper;
using MediatR;
using Provenance.Domain.User;
using Provenance.ErrorCount;
using Provenance.Infra.Interfaces.User;
using Provenance.Infra.Repositories;
using Provenance.Write.Api.Application.Command.User;

namespace Provenance.Write.Api.Application.CommandHandler.User
{
    public class UpdateUserCommandHandler : IRequestHandler<UpdateUserCommand, ApiResult>
    {
        private readonly IUserInfoRepository _userInfoRepository;
        private readonly IUserRoleRepository _userRoleRepository;
        private readonly ILogger<UpdateUserCommandHandler> _logger;
        private readonly IMapper _mapper;
        public UpdateUserCommandHandler(IUserInfoRepository userInfoRepository, IUserRoleRepository userRoleRepository, ILogger<UpdateUserCommandHandler> logger, IMapper mapper)
        {
            _userInfoRepository = userInfoRepository;
            _userRoleRepository = userRoleRepository;
            _logger = logger;
            _mapper = mapper;
        }
        public async Task<ApiResult> Handle(UpdateUserCommand request, CancellationToken cancellationToken)
        {
            try
            {
                using (var tran = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
                {
                    try
                    {
                        var obj = await _userInfoRepository.GetAsync(x => x.UserId == request.UserId);
                        obj = _mapper.Map(request, obj);
                        await _userInfoRepository.UpdateEntity(obj);
                        var list = await _userRoleRepository.GetAllAsync(x => x.UserId == request.UserId);
                        await _userRoleRepository.DeleteRangeEntity(list);
                        var userRoleList = new List<UserRole>();
                        string[] stringIds = request.RoleIds.Split(',');
                        int[] intIds = stringIds.Select(x => int.Parse(x)).ToArray();
                        foreach (var id in intIds)
                        {
                            userRoleList.Add(new UserRole { UserId = request.UserId, RoleId = id });
                        }
                        await _userRoleRepository.InsertRangeEntity(userRoleList);
                        tran.Complete();
                        return ApiResult.Success();
                    }
                    finally
                    {
                        tran.Dispose();
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error in UpdateUserCommandHandler.Handle: " + ex.Message);
                return ApiResult.Failure(ex.Message);
            }
        }
    }
}
